#include "ArchivoTexto.h"
#include "Exception.h"
#include "unistd.h"

using namespace std;

ArchivoTexto::ArchivoTexto(const std::string& path, bool sobreescrir) {

	if (!sobreescrir) {
		//intenta abrir el archivo en modo lectura - escritura
		archivo.open(path.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary);

		if (!archivo.is_open()) {
			//si no hubo exito en la apertura...
			//limpia los flags de control de estado del archivo
			archivo.clear();

			//crea el archivo
			archivo.open(path.c_str(), std::fstream::out);
			archivo.close();

			//reabre el archivo para lectura - escritura
			archivo.open(path.c_str(), std::fstream::in | std::fstream::out);

			if (!archivo.is_open())
				// si no se pudo crear el archivo arroja una excepción/
				throw Exception("El archivo no pudo ser abierto");
		}

	} else {
		//intenta abrir el archivo en modo lectura - escritura
		archivo.open(path.c_str(), std::fstream::in | std::fstream::out
				| std::fstream::trunc | std::fstream::binary);

		if (!archivo.is_open()) {
			//si no hubo exito en la apertura...
			//limpia los flags de control de estado del archivo
			archivo.clear();

			//crea el archivo
			archivo.open(path.c_str(), std::fstream::out);
			archivo.close();

			//reabre el archivo para lectura - escritura
			archivo.open(path.c_str(), std::fstream::in | std::fstream::out);

			if (!archivo.is_open())
				// si no se pudo crear el archivo arroja una excepción/
				throw Exception("El archivo no pudo ser abierto");
		}
	}
}


ArchivoTexto::~ArchivoTexto() {
	archivo.close();
}

void ArchivoTexto::escribir(char c) {
	// Intenta escribir el caracter en el archivo
	archivo.put(c);

	//si se produjo un error, arroja una excepción
	if (archivo.fail())
		throw Exception("No se pudo escribir correctamente el registro");
}

void ArchivoTexto::escribir(const std::string& cadena) {
	//intenta escribir la cadena en el archivo
	archivo << cadena;

	// si se produjo un error, arroja una excepción
	if (archivo.fail())
		throw Exception("No se pudo escribir correctamente la cadena");

	archivo.flush();
}

void ArchivoTexto::nuevaLinea() {
	// intenta escribir en el archivo
	archivo << endl;

	//si se produjo un error, arroja una excepción
	if (archivo.fail())
		throw Exception("No se pudo terminar la linea");
}

void ArchivoTexto::tab() {
	escribir('\t');
}

bool ArchivoTexto::leerLinea(std::string &cadena) {
	char linea[MAX_LENGTH];

	// lee del archivo a la linea, hasta haber leido:
	// MAX_LENGTH caracteres, o un fin de linea
	archivo.getline((char*) &linea, MAX_LENGTH, '\n');
	cadena = linea;

	if (archivo.fail()) {
		//chequea si se ha producido un error, se devuelve false
		archivo.clear();
		return false;
	}
	return true;
}

/**
 * Posiciona el cursor al comienzo del archivo
 */
void ArchivoTexto::irAlPrincipio() {
	archivo.tellg();
	archivo.clear();
	archivo.seekg(0);
	archivo.seekp(0);
	archivo.tellg();
}

/**
 * Posiciona el cursor al final del archivo
 */
void ArchivoTexto::irAlFinal() {
	archivo.tellg();
	archivo.clear();
	archivo.seekg(0, ios::end);
	archivo.seekp(0, ios::end);
	archivo.tellg();

}

bool ArchivoTexto::borrarArchivo(std::string fileName)
{
	if(::unlink(fileName.c_str())<0)
		return false;
	else
		return true;
}

